# -*- coding: utf-8 -*-
"""
解析HTML文件中的链接
"""
import ast
import datetime
import re

from bs4 import BeautifulSoup, NavigableString

from models import PackageInfo


pattern = re.compile(r'(?<=dl\().*(?=\))')


class WinPackHtmlParser():
    """
    解析指定的文件
    """

    def __init__(self, file_path):

        with open(file_path) as f:
            content = f.read()

        self.soup = BeautifulSoup(content)

        packages_base_infos = self.get_all_packages_base_infos()
        packages_details = self.get_all_packages_details()

        self.packages = {}

        for entry in packages_base_infos:
            key = entry.name.lower()
            self.packages[key] = packages_details.get(key, None)


    def get_all_packages_base_infos(self):
        """
        获取所有的包，这些信息在节点<ol></ol>中，只需要第一个（Index by date:），其他几个都没用
        :return: list(PackageInfo)
        """
        result = []
        package_names = self.soup.find_all('ol')[0]
        for child in package_names.children:
            if not isinstance(child, NavigableString):
                link = child.a
                if link:
                    name = link.string
                    compile_date = datetime.datetime.strptime(link['title'], '%b %d, %Y')
                    p = PackageInfo(name, compile_date)
                    result.append(p)
        return result

    def get_all_packages_details(self):
        """
        获取所有包的下载地址
        :return: dic
        """
        result = {}
        pylibs = self.soup.find('ul', class_='pylibs')
        for child in pylibs.children:
            if not isinstance(child, NavigableString):
                strong = child.strong
                if strong:
                    package_name = strong.string.lower()
                    urls = self.get_package_download_url(child.ul)
                    result[package_name] = urls
        return result

    @staticmethod
    def get_package_download_url(ul):
        """
        找出指定包的下载地址
        :param ul:
        :return:
        """
        result = []
        for child in ul.children:
            if not isinstance(child, NavigableString):
                download_name = child.string
                download_url = child.a.attrs['onclick'].replace('javascript:', '')
                # match = re.search(pattern, download_url)

                arg1 = re.search(r'\[.*\]', download_url).group()
                arg2 = re.search(r'(?<=").*(?=")', download_url).group()

                download_url = WinPackHtmlParser.decryption_url(arg1, arg2)
                result.append((download_name, download_url))
        return result

    @staticmethod
    def decryption_url(arg1, arg2):
        arg1 = ast.literal_eval(arg1)
        arg2 = arg2.replace('&lt;', '<').replace('&gt;', '>').replace('&amp;', '&')
        result = ''
        for j in range(len(arg2)):
            # String.fromCharCode(ml[mi.charCodeAt(j)-48])
            a = ord(arg2[j])
            b = a - 48
            c = arg1[b]
            d = chr(c)
            result += d
        return 'http://www.lfd.uci.edu/~gohlke/pythonlibs/' + result

    def get_package(self, package_name):
        """
        根据名称查找出包的信息
        :param package_name: str
        :return: PackageInfo
        """
        pass



